/*****************************************************************************//*!
* file  : systask.c
* creat : apleilx
* data  : 2017/11/05
*******************************************************************************/

#include "os_obj.h"
#define _SD_TASK_MODULE_
#include "sd_task.h"
#undef _SD_TASK_MODULE_
#include "pincfg.h"
#include "sys_init.h"
#include "com_obj.h"
#include "common.h"
#include "bsp_hal.h"
#include "bsp_spim.h"

#include "fx_api.h"

void file_tst(void);
void sd_io_check (void);
extern SD_CardInfo SDCardInfo; 

VOID  fx_sd_driver(FX_MEDIA *media_ptr);

FX_MEDIA        sd_disk;
FX_FILE         sd_file;
unsigned long   sd_media_memory[4096 /4];

#define FILE_W_TST_EN 1
#define FILE_R_TST_EN 0

/*****************************************************************************
*
* @brief   system task.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void sd_task (ULONG thread_input)
{
	(void)thread_input;
    
    /* Initialize FileX.  */
    fx_system_initialize();
    
    while(1)
    {
        osDelay(ms_ticks(20));
        
        sd_io_check();
        
        if(sd_st.connect.b_init_ok)
        {
            if(!sd_st.tst_end)
            {
                sd_st.tst_end = 1;
                file_tst();
            }
        }
        else
        {
            sd_st.tst_end = 0;
        }
    }
}

/*****************************************************************************
*
* @brief   sd cd check and init.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void sd_io_check (void)
{
    io_flt_extv2(&sd_st.sd_nc, 1,1,5,!io_sd_ncd.in_st());
    
    if(!sd_st.sd_nc.st.val)
    {
        sd_st.connect.b_cd_found = 0;
        sd_st.connect.b_init_ok = 0;
    }
    
    if(sd_st.sd_nc.st.edge_lost)
    {
        set_u8(&SDCardInfo, 0, sizeof(SD_CardInfo));
    }
    
    if(sd_st.sd_nc.found_time_cnt == 25)
    {
        sd_st.connect.b_cd_found = 1;
        
        sd_st.sd_nc.found_time_cnt++;
        
        nvic_irq_set(SDIO2_IRQn, 5, 1);
        
        if((sd_st.sd_opt_st = SD_Init()) == SD_OK)
        {
            sd_st.block_size = SDCardInfo.CardBlockSize;
            sd_st.total_size = SDCardInfo.CardCapacity;  
            
            sd_st.connect.b_init_ok = 1;
        }
    }
}

/*****************************************************************************
*
* @brief   file test.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void file_tst(void)
{
    ULONG actual, index, cnt;
    CHAR  local_buffer[128];

    //open spim disk
    sd_st.fil_opt_st = fx_media_open(&sd_disk,
        "SD DISK",
        fx_sd_driver,
        0,
        sd_media_memory,
        sizeof(sd_media_memory));

    do
    {
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            break;
        }

        /* Open the test file.  */
        sd_st.fil_opt_st = fx_file_open(&sd_disk, &sd_file, "main.c", FX_OPEN_FOR_READ);
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            break;
        }
        
        sd_st.fil_opt_st = fx_file_read(&sd_file, local_buffer, 60, &actual);
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            break;
        } 
        
        sd_st.fil_opt_st = fx_file_close(&sd_file);
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            break;
        } 
        
        /* Create a file called TEST.TXT in the root directory.  */
        sd_st.fil_opt_st = fx_file_create(&sd_disk, "FX_NEW.CSV");

        /* Check the create sd_st.fil_opt_st.  */
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            /* Check for an already created sd_st.fil_opt_st. This is expected on the
               second pass of this loop!  */
            if (sd_st.fil_opt_st != FX_ALREADY_CREATED)
            {
                /* Create error, break the loop.  */
                DBG_PRINT("FX_NEW.TXT creat: ERROR\n");
                break;
            }
            else
            {
                DBG_PRINT("FX_NEW.TXT creat: FX_ALREADY_CREATED\n");
            }
        }
        else
        {
            DBG_PRINT("FX_NEW.TXT creat: OK\n");
        }

        
        
        /* Open the test file.  */
        sd_st.fil_opt_st = fx_file_open(&sd_disk, &sd_file, "FX_NEW.CSV", FX_OPEN_FOR_WRITE);
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            break;
        } 
        
        /* point to end of the file.  */
        sd_st.fil_opt_st = fx_file_seek(&sd_file, sd_file.fx_file_current_file_size);
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            /* Error performing file seek, break the loop.  */
            DBG_PRINT("FX_NEW.TXT SEEK: ERROR\n");
            break;
        } 
        

        /* Write a string to the test file.  */
#if FILE_W_TST_EN > 0
        sd_st.fil_write_time = app_tick_get();
        
        for(index = 0; index < 1024; index++)
        {
            
            for(cnt = 0; cnt < 12; cnt++)
            {
                i32_to_string(&local_buffer[cnt * 10], index * 10 + cnt, 0x52, 0x10);
                local_buffer[cnt * 10 + 8] = ',';
                local_buffer[cnt * 10 + 9] = ' ';
            }
            
            local_buffer[cnt * 10 + 0] = '\r';
            local_buffer[cnt * 10 + 1] = '\n';
            
            sd_st.fil_opt_st = fx_file_write(&sd_file, local_buffer, cnt * 10 + 2);
        }
        
        sd_st.fil_write_time = app_tick_get() - sd_st.fil_write_time;
        sd_st.file_write_size = index * (cnt * 10 + 2);

        /* Check the file write sd_st.fil_opt_st.  */
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            DBG_PRINT("SPIM.TXT WRITE: ERROR\n");
            /* Error writing to a file, break the loop.  */
            break;
        }
#endif

        /* Seek to the beginning of the test file.  */
        sd_st.fil_opt_st = fx_file_seek(&sd_file, 0);

        /* Check the file seek sd_st.fil_opt_st.  */
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {
            DBG_PRINT("SPIM.TXT SEEK AFTER WRITE: ERROR\n");
            /* Error performing file seek, break the loop.  */
            break;
        }

#if FILE_R_TST_EN > 0
        /* Read the first 28 bytes of the test file.  */
        DBG_PRINT("SPIM.TXT READ DAT :\n");
        while (1)
        {
            sd_st.fil_opt_st = fx_file_read(&sd_file, local_buffer, 60, &actual);
            local_buffer[actual] = 0;

            /* Check the file read sd_st.fil_opt_st.  */
            if (sd_st.fil_opt_st != FX_SUCCESS)
            {
                if (sd_st.fil_opt_st != FX_END_OF_FILE)
                {
                    DBG_PRINT("SPIM.TXT READ: ERROR -%d\n", sd_st.fil_opt_st);
                    /* Error reading file, break the loop.  */
                    break;
                }
                else
                {
                    DBG_PRINT("%s", local_buffer);
                    break;
                }
            }

            DBG_PRINT("%s", local_buffer);

            osDelay(ms_ticks(10));
        }
        DBG_PRINT("\n\nSPIM FILE READ END!\n\n");

        /* Check the file read sd_st.fil_opt_st.  */
        if ((sd_st.fil_opt_st != FX_SUCCESS) && (sd_st.fil_opt_st != FX_END_OF_FILE))
        {
            break;
        }
#endif

        /* Close the test file.  */
        sd_st.fil_opt_st = fx_file_close(&sd_file);

        /* Check the file close sd_st.fil_opt_st.  */
        if (sd_st.fil_opt_st != FX_SUCCESS)
        {

            /* Error closing the file, break the loop.  */
            break;
        }

    } while (0);
    
    fx_media_close(&sd_disk);
}

